#!/usr/bin/python

from os.path import split, dirname, basename, isdir, isfile, exists
from os import system, listdir, mkdir, makedirs, mknod, remove
from shutil import copyfile, rmtree 

def backup_callback(sp, dp, bp):
    new_tag = '.new_' + basename(dp)
    if isdir(sp):
        if not exists(dp):
            #if dst dir is not exists, create it and make a tag
            print "make dir " + dp
            mkdir(dp)
            print "make new tag " + new_tag 
            mknod(dp + '/../' + new_tag)
        elif isfile(dp):
            #something wrong
            print "OOOPPPSSS! " + dp + "can not be file"
        else:
            #create backup path
            mkdir(bp)
            print "make dir " + dp
    else:
        if not exists(dp):
            copyfile(sp, dp)
            print "copy file " + sp + " to " + dp
            mknod(dirname(dp) + '/' + new_tag)
            print "make new tag " + new_tag 
        elif isdir(dp):
            print "OOOPPPSSS! " + dp + "can not be file"
        else:
            copyfile(dp, bp)
            print "copy file " + dp + " to " + bp
            copyfile(sp, dp)
            print "copy file " + sp + " to " + dp

def restore_callback(sp, dp, bp):
    new_tag = dp + '/../.new_' + basename(dp)
    print "!!!!!!!!!!!" + new_tag
    
    if exists(new_tag):
        print "remove new tag " + new_tag 
        remove(new_tag)
        print "remove " + dp
        rmtree(dp)
    
    if isfile(bp):
        copyfile(bp, dp);
        print "restore " + bp + " to " + dp

global callback_func

controller = {
        "backup": backup_callback,
        "restore": restore_callback,
        }

def backup_file(sp, dp, bp):
    global callback_func
    callback_func = controller.get("backup", None);
    traverse(sp, dp, bp, 0)

def restore_file(sp, dp, bp):
    global callback_func
    callback_func = controller.get("restore", None)
    traverse(sp, dp, bp, 0)

def traverse(sp, dp, bp, depth=0):
    global callback_func
    if isdir(sp):
        if callback_func and depth:
            callback_func(sp, dp, bp)
        for item in listdir(sp):
            print sp
            traverse(sp + '/' + item,
                dp + '/' + item,
                bp + '/' + item,
                depth+1)
    elif callback_func:
        callback_func(sp, dp, bp)

if __name__ == '__main__':
    system("mkdir bak")
    system("diff src dst -r > before_backup.diff")
    backup_file('src', 'dst', 'bak')
    system("diff src dst -r > after_backup.diff")
    restore_file('src', 'dst', 'bak')
    system("diff src dst -r > after_restore.diff")
    system('rm -rf bak/')
